home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- #
- # Exercise.c
- #
- # derived from MPW 3.1's "Sample", a MultiFinder-Aware Simple Sample Application
- #
- # Demonstrates how to use A/ROSE tasks for parallel processing
- # (one more program which computes Mandelbrot sets ...)
- #
- # One resizeable window; allows to select zoom-in rectangle
- # (was meant to be an introductory Macintosh C-programming exercise, originally)
- #
- # Refer to the original source code in the MPW CExamples folder for more comments
- #
- # Components:
- # Exercise.c
- # Exercise.r
- # Exercise.h
- # Exercise.make
- #
- ------------------------------------------------------------------------------*/
- /* -------------- MPW: select the following lines + <ENTER> ------
- Asm iter16.a
- C Exercise.c -r
- Link -o Exercise ∂
- Exercise.c.o iter16.a.o ∂
- ::IPCGlue.o ∂
- "{CLibraries}"CRuntime.o ∂
- "{CLibraries}"CInterface.o ∂
- "{Libraries}"Interface.o ∂
- "{CLibraries}"CSANElib.o
- Rez Exercise.r -o Exercise -a
- Exercise
- ---------------------------------------------------------------- */
-
- #include <Types.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Controls.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Packages.h>
- #include <DiskInit.h>
- #include <OSEvents.h>
- #include <OSUtils.h>
- #include <Traps.h>
- #include <SANE.h>
- #include <Strings.h>
-
- #include "Exercise.h" // bring in all the #defines for Exercise
-
- //---------------------------------------------------------------------------
- // A/ROSE declarations (from "os.h"):
-
- typedef long tid_type;
-
- struct mMessage
- {
- struct mMessage *mNext;
- long mId;
- short mCode;
- short mStatus;
- unsigned short mPriority;
- tid_type mFrom;
- tid_type mTo;
- unsigned long mSData [3];
- unsigned long mOData [3];
- long mDataSize; // Size of data buffer in bytes. set to negative
- // size of buffer if buffer is shared
- // between tasks. eg. Buffer cannot be copied
- char *mDataPtr;
- };
-
- typedef struct mMessage mMessage;
-
- #define OS_MATCH_ALL 0 // on receive match anything
- #define OS_NO_TIMEOUT 0 // receive waits forever for message
-
- // and some #define's from "managers.h":
-
- #define OS_UNKNOWN_MESSAGE (1<<8) // unknown message
- #define Machine_Visible 0 // Register_task Machine visible flag
-
- #define ICC_GETCARDS 150 // Get list of active cards and their name mgr TID
-
- //---------------------------------------------------------------------------
-
- // prototypes
-
- void Initialize(void);
- Boolean TrapAvailable(short tNumber, TrapType tType);
- void AlertUser(short error);
- void BigBadError(short error);
- Boolean DoCloseWindow(WindowPtr window);
- Boolean IsAppWindow(WindowPtr window);
- Boolean IsDAWindow(WindowPtr window);
- void Terminate();
-
- void DoMouseDown(EventRecord *theEvent);
- void DoContentClick(WindowPtr window, EventRecord *event);
- void EventLoop(void);
- void DoEvent(EventRecord *event);
- void DoUpdate(WindowPtr window);
- void DoActivate(WindowPtr window, Boolean becomingActive);
- void DrawWindow(WindowPtr window);
- void ShowCount(Boolean CPU);
- void AdjustMenus();
- void enable(MenuHandle menu, short item, Boolean okok);
- void DoMenuCommand(long mSelect);
- void InitNewRun();
- void ResetSlotServers();
- short NextLine(Ptr st, char **linePtr);
- void DoCPUcomputation(void);
- void UpdateBitmap(short y, Boolean CPU);
- void Mandelbrot(void);
- Boolean MakeOffScreen();
- void CreateMyWindow(void);
- void DoGrowWindow(WindowPtr window, EventRecord *event);
- short AROSEPrep(tid_type *t);
- Boolean AskICCM(char *Cards);
- short FindAllServers(char *name, char *type);
- void GetnewSelection(void);
- void StringCopy(char *s, char *t);
- extern pascal short ITER16(short cx, short cy, short gNmax);
-
- // A/ROSE prototypes: --------------------
-
- extern mMessage *GetMsg(void);
- extern void FreeMsg();
- extern mMessage *Receive();
- extern void Send(mMessage *);
-
- extern tid_type GetTID(void);
- extern tid_type GetICCTID(void);
- extern char Register_Task();
- extern tid_type Lookup_Task(char *, char *, tid_type, unsigned short *);
- extern unsigned short GetTickPS();
-
- extern tid_type OpenQueue();
- extern void CloseQueue();
- //----------------------------------------
-
- // Define HiWrd and LoWrd macros for efficiency.
- #define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
- #define LoWrd(aLong) ((aLong) & 0xFFFF)
-
-
- // global variables
-
- SysEnvRec gMac; // set up by Initialize
- Boolean gHasWaitNextEvent; // set up by Initialize
- Boolean gInBackground; // maintained by Initialize and DoEvent
- WindowPtr gMyWindow;
- tid_type gTID; // my task identifier returned by OpenQueue()
- // = 0 if A/ROSE not available
-
- Rect gRect; // to display Mandelbrot set in gMyWindow
- ControlHandle gCPUctlH,
- gMCPctlH; // checkboxes to activate parallel computation
-
- Boolean gDone;
- gCPU = false;
- gMCP = false;
- gMCPpending[16]; // waiting for an A/ROSE message from a slot ?
-
- tid_type gServerTID[16]; // TID's of MBServers in NuBus slots
-
- BitMap gOffScreen;
-
- enum {empty, busy, full}; // track state of each line to compute
- typedef unsigned char state;
- state gLineState[kMaxHeight];
-
-
- struct MBvariables { // used in Mandelbrot(), InitNewRun() and ShowCount()
- short nmax; // max. depth of iteration
- short d; // corresponding to coord. distance between pixels
- short cx, cy; // current point of the complex plane to be computed
- // these first eight bytes are parameters for the MBTask !
- short yMCP;
- short ix, iy; // counters 0..nx-1, 0..ny-1
- short xa, ya; // topleft point in the complex plane
-
- short nx, ny; // size of rectangle
- short cntCPU, cntMCP; // number of lines computed
- extended ncenterx,
- ncentery,
- nxextent; // initial default values (coord. in the complex plane)
- extended centerx,
- centery,
- xextent; // coordinates after zooming in
- };
-
- typedef struct MBvariables MBvariables;
-
- MBvariables gMBvars;
-
- extern void _DataInit();
-
- //===============================
- main()
- //===============================
- {
- UnloadSeg((Ptr) _DataInit); // note that _DataInit must not be in Main!
-
- MaxApplZone(); // expand the heap so code segments load at the top
-
- Initialize(); // initialize the program
- UnloadSeg((Ptr) Initialize); // note that Initialize must not be in Main!
-
- EventLoop(); // call the main event loop
-
- }
-
-
- #pragma segment Initialize
- //===============================
- void Initialize(void)
- //===============================
- {
- Handle menuBar;
- long total, contig;
- EventRecord event;
- short count, result;
- Ptr windowP;
-
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- gInBackground = false;
-
- // This next bit of code is necessary to allow the default button of our
- // alert be outlined.
-
- for (count = 1; count <= 3; count++)
- EventAvail(everyEvent, &event);
-
- SysEnvirons(kSysEnvironsVersion, &gMac);
-
- if (gMac.machineType < 0)
- BigBadError(eWrongMachine);
-
- if (! TrapAvailable(_WaitNextEvent, ToolTrap))
- BigBadError(eWrongMachine);
-
- if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap)
- BigBadError(eSmallSize);
-
- // ZeroScrap();
-
- PurgeSpace(&total, &contig);
- if (total < kMinSpace)
- BigBadError(eNoMemory);
-
- gTID = 0; // in case A/ROSE will not be available
- result = AROSEPrep(&gTID); // side effect: returns gServerTID[0..15] !
- if (result != noErr) {
- if (gTID > 0) { // if we registered with .IPC --
- CloseQueue(); // better clean up
- gTID = 0;
- }
- AlertUser(result);
- }
- for (count = 0; count < 16; count++)
- gMCPpending[count] = false;
-
- windowP = NewPtr(sizeof(WindowRecord)); // we allocate storage ourselves
- if ( windowP == nil )
- BigBadError(eNoWindow);
-
- gMyWindow = GetNewWindow(rWindow, windowP, (WindowPtr) -1);
- if ( gMyWindow == nil )
- BigBadError(eNoWindow);
-
- gRect = gMyWindow->portRect;
- InsetRect(&gRect, kBord, kBord);
- gRect.bottom = gRect.bottom - kBottom + kBord;
-
- if (!MakeOffScreen())
- BigBadError(eNoBitMap);
-
- gCPUctlH = GetNewControl(rCPUchk, gMyWindow); // to activate CPU computation
- gMCPctlH = GetNewControl(rMCPchk, gMyWindow); // to activate MCP computation
-
- if ((gCPUctlH == nil) | (gMCPctlH == nil))
- BigBadError(eNoWindow);
- MoveControl(gCPUctlH , gRect.left, gRect.bottom + 8);
- MoveControl(gMCPctlH , gRect.left, gRect.bottom + 24);
-
- gMBvars.ncenterx = -0.5;
- gMBvars.ncentery = 0.0;
- gMBvars.nxextent = 3.0;
-
- InitNewRun(); // initializes the other fields of gMBvars, resets MBTasks etc.
-
- menuBar = GetNewMBar(rMenuBar); // read menus into menu bar
- if ( menuBar == nil )
- BigBadError(eNoMemory);
- SetMenuBar(menuBar); // install menus
- DisposHandle(menuBar);
- AddResMenu(GetMHandle(mApple), 'DRVR'); // add DA names to Apple menu
- DrawMenuBar();
-
- } //Initialize
-
-
- #pragma segment Initialize
- //===============================
- Boolean TrapAvailable(short tNumber, TrapType tType)
- //===============================
- {
- if ( ( tType == ToolTrap ) &&
- ( gMac.machineType > envMachUnknown ) &&
- ( gMac.machineType < envMacII ) ) { // it's a 512KE, Plus, or SE
- tNumber = tNumber & 0x03FF;
- if ( tNumber > 0x01FF ) // which means the tool traps
- tNumber = _Unimplemented; // only go to 0x01FF
- }
- return NGetTrapAddress(tNumber, tType) != GetTrapAddress(_Unimplemented);
- } //TrapAvailable
-
-
- #pragma segment Main
- //===============================
- void Terminate()
- //===============================
- {
- WindowPtr aWindow;
- Boolean closed;
-
- if (gTID > 0) {
- ResetSlotServers();
- CloseQueue(); // Clean up interaction with A/ROSE Prep
- }
-
- if (gOffScreen.baseAddr != nil)
- DisposPtr(gOffScreen.baseAddr);
-
- closed = true;
- do {
- aWindow = FrontWindow(); // get the current front window
- if (aWindow != nil)
- closed = DoCloseWindow(aWindow); // close this window
- }
- while (closed && (aWindow != nil));
- if (closed)
- ExitToShell(); // exit if no cancellation
- } // Terminate
-
-
- #pragma segment Main
- //===============================
- Boolean DoCloseWindow(WindowPtr window)
- //===============================
- {
- if ( IsDAWindow(window) )
- CloseDeskAcc(((WindowPeek) window)->windowKind);
- else if ( IsAppWindow(window) )
- CloseWindow(window);
- return true;
- } //DoCloseWindow
-
-
- #pragma segment Main
- //===============================
- Boolean IsAppWindow(WindowPtr window)
- //===============================
- {
- short windowKind;
-
- if ( window == nil )
- return false;
- else { // application windows have windowKinds = userKind (8)
- windowKind = ((WindowPeek) window)->windowKind;
- return (windowKind = userKind);
- }
- } //IsAppWindow
-
-
- #pragma segment Main
- //===============================
- Boolean IsDAWindow(WindowPtr window)
- //===============================
- {
- if ( window == nil )
- return false;
- else // DA windows have negative windowKinds
- return ((WindowPeek) window)->windowKind < 0;
- } //IsDAWindow
-
-
- #pragma segment Main
- //===============================
- void AlertUser( short error)
- //===============================
- {
- short itemHit;
- Str255 errMsg;
-
- SetCursor(&qd.arrow);
- if ((error>0)&&(error<=kLastErrStr)) {
- GetIndString(errMsg, rErrStrings, error);
- ParamText(errMsg, "", "", "");
- }
- else {
- NumToString(error, &errMsg);
- ParamText("\pUnknown error", errMsg, "", "");
- }
-
- itemHit = Alert(rUserAlert, nil);
- } // AlertUser
-
- #pragma segment Main
- //===============================
- void BigBadError( short error)
- //===============================
- {
- AlertUser(error);
- ExitToShell();
- }
-
- #pragma segment Main
- //===============================
- void AdjustMenus()
- //===============================
- {
- WindowPtr window;
- MenuHandle menu;
-
- window = FrontWindow();
-
- menu = GetMHandle(mFile);
-
- if ( IsDAWindow(window) ) // we can allow desk accessories to be closed from the menu
- EnableItem(menu, iClose);
- else
- DisableItem(menu, iClose); // but not our only window
- EnableItem(menu, iNew);
- EnableItem(menu, iReset);
- EnableItem(menu, iQuit);
-
- menu = GetMHandle(mEdit);
- if ( IsDAWindow(window) ) { // a desk accessory might need the edit menu…
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iClear);
- EnableItem(menu, iPaste);
- } else { // …but we don’t use it
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
- } //AdjustMenus
-
-
-
- #pragma segment Main
- //===============================
- void DoMenuCommand (menuResult)
- //===============================
- long menuResult;
- {
- short menuID = HiWord(menuResult);
- short menuItem = LoWord(menuResult);
- short daRefNum;
- short itemHit;
- Str255 daName;
-
- switch (menuID)
- {
- case mApple:
- switch ( menuItem ) {
- case iAbout: // bring up alert for About
- itemHit = Alert(rAboutAlert, nil);
- break;
- default: // non-About items in this menu are DAs
- GetItem(GetMHandle(mApple), menuItem, daName);
- daRefNum = OpenDeskAcc(daName);
- break;
- }
- break;
-
- case mFile:
- switch (menuItem)
- {
- case iNew:
- InitNewRun();
- break;
-
- case iReset:
- gMBvars.ncenterx = -0.5;
- gMBvars.ncentery = 0.0;
- gMBvars.nxextent = 3.0;
- InitNewRun();
- break;
-
- case iQuit:
- Terminate();
- break;
- }
- break;
-
- case mEdit:
- if (!SystemEdit(menuItem-1))
- SysBeep(5);
- break;
-
- }
- HiliteMenu(0); // unhighlight what MenuSelect (or MenuKey) hilited
- }
-
-
- #pragma segment Main
- //===============================
- void DoContentClick(WindowPtr window, EventRecord *event)
- //===============================
- {
- Point mouse;
- ControlHandle control;
- short dummy;
-
- if ( IsAppWindow(window) ) {
- SetPort(window);
- mouse = event->where; // get the click position
- GlobalToLocal(&mouse);
- if ( FindControl(mouse, window, &control) == inCheckBox) {
- dummy = TrackControl(control, mouse, nil);
- if (control==gCPUctlH) {
- gCPU = !gCPU;
- SetCtlValue(gCPUctlH, (short)gCPU);
- }
- if (control==gMCPctlH) {
- gMCP = !gMCP;
- SetCtlValue(gMCPctlH, (short)gMCP);
- }
- }
- else if (PtInRect(mouse, &gRect))
- GetnewSelection();
- }
- }
-
-
- #pragma segment Main
- //===============================
- void ShowCount(Boolean CPU)
- //===============================
- {
- Rect rr;
- Str255 s;
-
- SetRect(&rr, gRect.left+kCntPos, gRect.bottom+6, gRect.left+kCntPos+30, gRect.bottom+20);
- if (!CPU) OffsetRect(&rr,0,16);
- if (CPU)
- NumToString(gMBvars.cntCPU,s);
- else
- NumToString(gMBvars.cntMCP,s);
- EraseRect(&rr);
- MoveTo(rr.left,rr.bottom);
- DrawString(s);
- }
-
- #pragma segment Main
- //===============================
- void DrawWindow(WindowPtr window)
- //===============================
- {
- RgnHandle rh;
- Rect cr;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(window);
- InsetRect(&gRect,-1,-1);
- FrameRect(&gRect);
- InsetRect(&gRect,1,1);
- EraseRect(&gRect);
- CopyBits(&gOffScreen, &(window->portBits), &gRect, &gRect, srcCopy, nil);
-
- if (gTID > 0)
- HiliteControl(gMCPctlH, 0); // MCP enabled
- else
- HiliteControl(gMCPctlH, 255); // MCP disabled
-
- DrawControls(window);
-
- ShowCount(true);
- ShowCount(false);
-
- rh = NewRgn();
- GetClip(rh);
- cr = window->portRect;
- cr.top = cr.bottom - 14;
- cr.left = cr.right - 14;
- ClipRect(&cr);
- DrawGrowIcon(window);
- SetClip(rh);
- SetPort(savePort);
- }
-
-
- #pragma segment Main
- //===============================
- void UpdateBitmap(short y, Boolean MCP)
- //===============================
- {
- Rect ir;
- GrafPtr savePort;
-
- ir = gRect;
- ir.top = ir.top + y;
- ir.bottom = ir.top + 1;
-
- GetPort(&savePort);
- SetPort(gMyWindow);
- InvalRect(&ir);
- ShowCount(!MCP);
- SetPort(savePort);
- }
-
-
- #pragma segment Main
- //===============================
- void Mandelbrot(void)
- //===============================
- {
- static char *linestart;
- short cx, cy, ty;
- short slot;
- mMessage *m;
- char *MCPbuffer;
-
- if (gCPU) {
- if (gMBvars.iy<0)
- gMBvars.iy = NextLine(gLineState, &linestart);
-
- if (gMBvars.iy < gMBvars.ny) {
- cx = gMBvars.xa + gMBvars.d*gMBvars.ix;
- cy = gMBvars.ya + gMBvars.d*gMBvars.iy;
-
- if (ITER16(cx, cy, gMBvars.nmax) & 0x1)
- BitSet(linestart,gMBvars.ix);
-
- gMBvars.ix += 1;
- if (gMBvars.ix == gMBvars.nx) {
- gLineState[gMBvars.iy] = full;
- gMBvars.cntCPU += 1;
- UpdateBitmap(gMBvars.iy, false);
- gMBvars.iy = NextLine(gLineState, &linestart);
- gMBvars.ix = 0;
- }
- }
- }
-
- for (slot = 0; slot<16; slot++) {
- if (gMCPpending[slot]) {
- m = Receive(OS_MATCH_ALL, gServerTID[slot], OS_MATCH_ALL, -1L, nil);
- // accept all message IDs,
- // accept messages coming from gServerTID[slot] only
- // accept all message codes
- // -1L: return without waiting
- // nil: no completion routine
-
- if ((long) m > 0) {
- ty = m->mOData[0]; // line number sent back by server
- if (m->mStatus == 0) {
- gMCPpending[slot] = false;
- gLineState[ty] = full;
- gMBvars.cntMCP += 1;
- UpdateBitmap(ty, true);
- }
- else {
- if (m->mStatus == OS_UNKNOWN_MESSAGE)
- AlertUser(eUnknownMsg);
- else {
- AlertUser(eUndeliverable);
- gMCPpending[slot] = false;
- gLineState[ty] = empty;
- gServerTID[slot] = 0; // no server any more in this slot!
- }
- }
- FreeMsg(m);
- }
- }
- if (gMCP && !gDone && !gMCPpending[slot] && (gServerTID[slot]>0)) {
- gMBvars.yMCP = NextLine(gLineState, &MCPbuffer);
- if (gMBvars.yMCP < gMBvars.ny) {
- m = GetMsg();
- if ((long)m == 0)
- DebugStr("\pGetMsg failed");
-
- // m->mFrom : filled in by GetMsg();
- m->mTo = gServerTID[slot];
- m->mCode = MBCODE;
- gMBvars.cx = gMBvars.xa;
- gMBvars.cy = gMBvars.ya + gMBvars.d*gMBvars.yMCP;
- BlockMove((char *)&gMBvars, (char *)&m->mSData[0], 12); // sender defined data !
-
- m->mDataSize = gOffScreen.rowBytes;
- m->mDataPtr = MCPbuffer;
- Send(m);
- gMCPpending[slot] = true;
- }
- else
- gDone = true;
- }
- }
- }
-
-
- #pragma segment Main
- //===============================
- void EventLoop()
- //===============================
- {
- EventRecord event;
-
- do {
- if (WaitNextEvent(everyEvent, &event, 0L, nil)) // minimum sleep value ...
- DoEvent(&event);
-
- else // idle time !
- Mandelbrot();
-
- } while (true); // loop forever; we quit via Terminate/ExitToShell
- } //EventLoop
-
-
- #pragma segment Main
- //===============================
- void DoEvent(EventRecord *event)
- //===============================
- {
- short part, err;
- WindowPtr window;
- char key;
- Point aPoint;
-
- switch ( event->what ) {
- case mouseDown:
- part = FindWindow(event->where, &window);
- switch ( part ) {
- case inMenuBar: // process a mouse menu command (if any)
- AdjustMenus();
- DoMenuCommand(MenuSelect(event->where));
- break;
- case inSysWindow: // let the system handle the mouseDown
- SystemClick(event, window);
- break;
- case inDrag: // pass screenBits.bounds to get all gDevices
- DragWindow(window, event->where, &qd.screenBits.bounds);
- break;
- case inGrow:
- if (window == gMyWindow)
- DoGrowWindow(window, event);
- break;
- case inContent:
- if ( window != FrontWindow() ) {
- SelectWindow(window);
- } else
- DoContentClick(window, event);
- break;
- }
- break;
- case keyDown:
- case autoKey: // check for menukey equivalents
- key = event->message & charCodeMask;
- if ( event->modifiers & cmdKey ) // Command key down
- if ( event->what == keyDown ) {
- AdjustMenus(); // enable/disable/check menu items properly
- DoMenuCommand(MenuKey(key));
- }
- break;
- case activateEvt:
- DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
- break;
- case updateEvt:
- DoUpdate((WindowPtr) event->message);
- break;
- case diskEvt:
- if ( HiWord(event->message) != noErr ) {
- SetPt(&aPoint, kDILeft, kDITop);
- err = DIBadMount(aPoint, event->message);
- // so that the user can format a floppy.
- }
- break;
- case kOSEvent:
- switch ((event->message >> 24) & 0x0FF) { // high byte of message
- case kSuspendResumeMessage: // suspend/resume is also an activate/deactivate
- gInBackground = (event->message & kResumeMask) == 0;
- DoActivate(FrontWindow(), !gInBackground);
- break;
- }
- break;
- }
- } //DoEvent
-
-
- #pragma segment Main
- //===============================
- void DoUpdate(WindowPtr window)
- //===============================
- {
- if ( IsAppWindow(window) ) {
- BeginUpdate(window); // this sets up the visRgn
- // draw if updating needs to be done
- if ( ! EmptyRgn(window->visRgn) )
- DrawWindow(window);
- EndUpdate(window);
- }
- } //DoUpdate
-
-
- #pragma segment Main
- //===============================
- void DoActivate(WindowPtr window, Boolean becomingActive)
- //===============================
- {
- if ( IsAppWindow(window) ) {
- if ( becomingActive )
- ; // do whatever you need to at activation
- else
- ; // do whatever you need to at deactivation
- }
- } //DoActivate
-
-
- #pragma segment Main
- //===============================
- void DoGrowWindow(WindowPtr window, EventRecord *event)
- //===============================
- {
- long growResult;
- Rect tempRect;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(gMyWindow);
- tempRect.left = kMinWidth;
- tempRect.top = kMinHeight;
- tempRect.right = kMaxWidth;
- tempRect.bottom = kMaxHeight;
- growResult = GrowWindow(window, event->where, &tempRect);
- if ( growResult != 0 ) {
- EraseRect(&window->portRect);
- SizeWindow(window, LoWord(growResult), HiWord(growResult), true);
- SetRect(&gRect, kBord, kBord, LoWord(growResult)-kBord, HiWord(growResult)-kBottom);
- MoveControl(gCPUctlH , gRect.left, gRect.bottom + 8);
- MoveControl(gMCPctlH , gRect.left, gRect.bottom + 24);
- InitNewRun(&gOffScreen);
- }
- SetPort(savePort);
- }
-
-
- #pragma segment Main
- //===============================
- short NextLine(Ptr st, char **linePtr)
- //===============================
- {
- short n;
-
- n = 0;
- while ((n<gMBvars.ny) && ((state)st[n] != empty))
- n++;
- if (n<gMBvars.ny) {
- (state)st[n] = busy;
- *linePtr = (char *)gOffScreen.baseAddr + (n * gOffScreen.rowBytes);
- }
- return n;
- }
-
-
- #pragma segment Main
- //===============================
- void InitNewRun()
- //===============================
- {
- short i;
- Ptr p;
- GrafPtr savePort;
-
-
- if (gTID > 0)
- ResetSlotServers();
-
- for (i=0; i<=kMaxHeight; gLineState[i++]=empty)
- ;
- gOffScreen.bounds = gRect;
- i = (gOffScreen.rowBytes)*(gOffScreen.bounds.bottom - gOffScreen.bounds.top);
- p = gOffScreen.baseAddr;
- while (i-- >0)
- *p++ = 0;
-
- gMBvars.ix = 0;
- gMBvars.iy = -1;
- gMBvars.yMCP = -1;
- gMBvars.cntCPU = 0;
- gMBvars.cntMCP = 0;
- gMBvars.nx = gRect.right-gRect.left;
- gMBvars.ny = gRect.bottom-gRect.top;
- gMBvars.centerx = gMBvars.ncenterx;
- gMBvars.centery = gMBvars.ncentery;
- gMBvars.xextent = gMBvars.nxextent;
- if (gMBvars.xextent > 0.5)
- gMBvars.nmax = 50;
- else if (gMBvars.xextent > 0.05)
- gMBvars.nmax = 80;
- else if (gMBvars.xextent > 0.005)
- gMBvars.nmax = 120;
- else
- gMBvars.nmax = 200;
- gMBvars.d = rint(kDenom * gMBvars.xextent / gMBvars.nx + 0.5);
- gMBvars.xa = rint(kDenom * (gMBvars.centerx - 0.5*gMBvars.xextent) + 0.5);
- gMBvars.ya = rint(kDenom * gMBvars.centery + 0.5) - gMBvars.ny * gMBvars.d / 2;
-
- gDone = false;
-
- GetPort(&savePort);
- SetPort(gMyWindow);
- InvalRect(&gMyWindow->portRect);
- SetPort(savePort);
-
- } // InitNewRun
-
-
- #pragma segment Main
- //===============================
- void ResetSlotServers()
- //===============================
- // this routine badly needs a re-design ... there are some major flaws in it
- {
- short slot;
- mMessage *m;
-
- for (slot=0; slot<16; slot++) {
- if (gMCPpending[slot]) {
- m = Receive(OS_MATCH_ALL, gServerTID[slot], OS_MATCH_ALL, (long)GetTickPS(), nil);
- // look for message coming from gServerTID[slot], timeout 1 second
- if ((long) m > 0) {
- if (m->mStatus != 0) { // message was undeliverable
- AlertUser(eUndeliverable);
- gServerTID[slot] = 0; // no server any more in this slot!
- }
- FreeMsg(m); // dispose of this message anyway
- }
- gMCPpending[slot] = false;
- } // if gMCPpending
-
- } // for each slot
-
- // is there still an active MBTask around ?
- // gServerTID[slot] could have been set to 0 if undeliverable messages were received
- slot = 0;
- while ((slot<16) && (gServerTID[slot] == 0))
- slot++;
- if (slot==16) { // no use of A/ROSE any more
- CloseQueue();
- gMCP = false;
- SetCtlValue(gMCPctlH, (short)gMCP);
- gTID = 0; // MCP checkbox will be disabled on next redraw
- }
- } // ResetSlotServers()
-
-
- #pragma segment Initialize
- //===============================
- Boolean MakeOffScreen()
- //===============================
- {
- long offRowBytes;
-
- offRowBytes = ((kMaxWidth + 15) >> 4 ) << 1;
-
- gOffScreen.baseAddr = NewPtrClear(offRowBytes*kMaxHeight);
- gOffScreen.rowBytes = offRowBytes;
- gOffScreen.bounds = gRect;
- return (gOffScreen.baseAddr != nil);
- }
-
-
-
- #pragma segment Initialize
- //===============================
- short AROSEPrep(tid_type *t)
- //===============================
- {
- StringHandle sh;
- Str255 clientName = "?", clientType = "?",
- taskName = "?", taskType = "?"; // wasting lots of RAM, eh ?
-
-
- sh = GetString(rClientName);
- if (sh != nil)
- StringCopy(*sh,clientName);
- sh = GetString(rClientType);
- if (sh != nil)
- StringCopy(*sh,clientType);
-
- *t = OpenQueue(nil);
- if (t == 0) { // A/ROSE Prep out of order
- return(eNoAROSE);
- }
- if (!Register_Task (p2cstr(&clientName), p2cstr(&clientType), Machine_Visible))
- AlertUser(eRegister);
-
- sh = GetString(rTaskName);
- if (sh != nil)
- StringCopy(*sh,taskName);
- sh = GetString(rTaskType);
- if (sh != nil)
- StringCopy(*sh,taskType);
- if (FindAllServers(p2cstr(&taskName), p2cstr(&taskType)) > 0)
- return(noErr);
- else return(eNoServer);
- }
-
-
- #pragma segment Initialize
- //===============================
- short FindAllServers(char *name, char *type)
- //===============================
- // compare this with "ShowTasks.c" !
- {
- short slot;
- tid_type tid, // (result of Lookup_Task call)
- sTID; // the Name Manager TID for a given slot
- tid_type nCards[16]; // ICCM will fill in the Name Manager TID's
- unsigned short index, agentsThere;
-
-
- if (! AskICCM((char *)nCards)) {
- AlertUser(eICCMproblem);
- return 0;
- }
-
- slot = 0;
- tid = 0;
- agentsThere = 0;
- do {
- index = 0;
- gServerTID[slot] = 0L;
- if (sTID = nCards[slot])
- gServerTID[slot] = Lookup_Task(name, type, sTID, &index);
- if (gServerTID[slot])
- agentsThere += 1;
- } while (slot++ < 16);
- return agentsThere;
- }
-
-
- #pragma segment Initialize
- //===============================
- Boolean AskICCM(char *Cards)
- //===============================
- {
- Boolean result;
- mMessage *m;
-
- if (GetICCTID() == 0)
- return(false);
-
- if ((m = GetMsg()) == 0)
- return(false);
-
- m->mTo = GetICCTID ();
- m->mCode = ICC_GETCARDS;
- m->mDataPtr = Cards;
- m->mDataSize = sizeof(tid_type) * 16;
- Send(m);
- m = Receive(OS_MATCH_ALL, OS_MATCH_ALL, ICC_GETCARDS+1, OS_NO_TIMEOUT, nil);
- // look for message with mCode = ICC_GETCARDS+1
- result = (m->mStatus == 0); // slotInfo is in Cards[0..15] !
- FreeMsg(m);
- return(result);
-
- } // AskICCM()
-
-
- #pragma segment Main
- //===============================
- void GetnewSelection()
- //===============================
- {
- Point ratio, startPt, anewPt, newPt;
- Rect tempRect;
- short ncx, ncy;
-
- #define abs(x) ((x) >= 0) ? (x) : -(x)
-
- ratio.h = gMBvars.nx; ratio.v = gMBvars.ny;
- PenMode(patXor);
- PenPat(qd.gray);
- GetMouse(&startPt);
- SetRect(&tempRect, startPt.h, startPt.v, startPt.h, startPt.v);
- while (Button()) {
- FrameRect(&tempRect);
- GetMouse(&newPt);
- SubPt(startPt, &newPt);
- anewPt.h = abs(newPt.h);
- anewPt.v = abs(newPt.v);
-
- if (anewPt.h*ratio.v < anewPt.v*ratio.h)
- newPt.h = newPt.v * ratio.h / ratio.v;
- else
- newPt.v = newPt.h * ratio.v / ratio.h;
- SetRect(&tempRect,
- startPt.h, startPt.v, startPt.h+newPt.h, startPt.v+newPt.v);
- FrameRect(&tempRect);
- }
- PenNormal();
- ncx = (gRect.left + gRect.right - tempRect.left - tempRect.right)/2;
- ncy = (gRect.top + gRect.bottom - tempRect.top - tempRect.bottom)/2;
- gMBvars.ncenterx = gMBvars.centerx - gMBvars.xextent*ncx/gMBvars.nx;
- gMBvars.ncentery = gMBvars.centery - gMBvars.xextent*ncy/gMBvars.nx;
- gMBvars.nxextent = gMBvars.xextent*(tempRect.right - tempRect.left)/gMBvars.nx;
- }
-
-
- #pragma segment Initialize
- //===============================
- void StringCopy(char *s, char *t)
- //===============================
- {
- short n= (*t++ = *s++);
- while (n-- >0)
- *t++ = *s++;
- }
-